import { findIndex } from 'lodash';
import type { AudPageMenuItem, AudTab } from './types';
import { intl } from '@/utils';
import type { MenuDataItem } from '@ant-design/pro-layout';
import type { SysName } from '@/layouts';

/**
 * AudTabPage 类 用来处理 tabs的显示等
 * 改文件使用 any类型是因为 目前官网没有找到相关定义
 */
class AudTabPage {
  private routes: MenuDataItem[]; // 全量路由
  private pages: AudTab[]; // 页签中可以打开的功能
  public tabs: AudTab[];
  public activeTabKey!: string;
  public notfind: boolean;

  private constructor() {
    this.routes = [];
    this.pages = [];
    this.tabs = [];
    this.activeTabKey = '/';
    this.notfind = true;
  }
  private static instance: AudTabPage;
  public static getInstance(): AudTabPage {
    if (this.instance == null) {
      this.instance = new AudTabPage();
    }
    return this.instance;
  }
  /**
   * 增加route到tab如果有直接退出，没有就增加
   * @param matchedRoutes 匹配到的所有route
   * @param route
   * @returns 已存在返回 false 增加成功返回 true
   */
  private pushTab(page: AudTab): boolean {
    const index = findIndex(this.tabs, { key: page.key });
    if (index >= 0) {
      this.activeTabKey = page.key;
      // 刷新的时候，先将 content = undefined
      // if (this.tabs[index].content === undefined) {
      //   this.tabs[index].content = route.component;
      // }
      return false;
    }
    this.tabs.push(page);
    return true;
  }

  /**
   * 关闭一个页
   * @param key
   */
  public closeTabByKey(key: string): string | null {
    let lastIndex = -1;
    this.tabs.forEach((tab, i) => {
      if (tab.key === key) {
        lastIndex = i - 1;
      }
    });
    this.tabs = this.tabs.filter((tab) => tab.key !== key);

    if (this.tabs.length && this.activeTabKey === key) {
      if (lastIndex >= 0) {
        this.activeTabKey = this.tabs[lastIndex].key;
      } else {
        this.activeTabKey = this.tabs[0].key;
      }
    }
    return this.activeTabKey;
  }

  public closeTab(act: AudPageMenuItem) {
    if (act === 'closeCur') {
      this.closeTabByKey(this.activeTabKey);
    } else if (act === 'closeOther') {
      this.tabs = this.tabs.filter(
        (tab) => tab.key === this.activeTabKey || tab.closable === false,
      );
    } else if (act === 'closeAll') {
      this.tabs = this.tabs.filter((tab) => tab.closable === false);
      this.activeTabKey = '/home';
    } else if (act === 'refresh') {
      const index = findIndex(this.tabs, { key: this.activeTabKey });
      if (index >= 0) {
        // 刷新的时候，先将 content = undefined
        this.tabs[index].content = undefined;
      }
    }
  }

  public setRoutes(Routes: any[]) {
    const { routes } = Routes[Routes.length - 1];
    this.routes = routes;
  }

  /**
   * 要放在 export function onRouteChange(Route: any) 下
   * @param Route
   * @returns
   */
  public showPage(location: Location & { state: any }) {
    this.notfind = false;
    const index = findIndex(this.pages, { key: location.pathname });
    if (index >= 0) {
      this.pushTab(this.pages[index]);
    } else {
      this.notfind = true;
    }
    if (location.pathname === '/') {
      this.activeTabKey = '/home';
    } else {
      this.activeTabKey = location.pathname;
    }
    if (location.state) {
      const indexTab = findIndex(this.tabs, { key: location.pathname });
      if (indexTab >= 0) {
        this.tabs[indexTab].state = location.state;
      }
    }
  }

  public initPages(sysName: SysName) {
    this.tabs = [];
    this.pages = [];
    // item 是否有权限
    const getAccess = (item: MenuDataItem): boolean => {
      if (!item.access) return true;
      if (!item.flatMenu) return true;
      if (item.access === sysName && item.flatMenu === true) return true;
      return false;
    };
    // 从全量 routes 中获取可以在tab中显示的页
    const getPages = (items: any, fullname: string) => {
      items.forEach((item: MenuDataItem) => {
        if (item.layout === false) return; // 有layout的不加入
        let newFullname = fullname; // 用于获取多语言的
        if (item.name) {
          newFullname = `${newFullname}.${item.name}`;
        }
        if (getAccess(item)) {
          if (item.children) {
            getPages(item.children, newFullname);
          } else if (item.component) {
            const page: AudTab = {
              key: item.path || '',
              icon: item.icon,
              title: intl(newFullname, item.name),
              content: item.component,
              closable: item.closable,
            };
            if (item.closable !== undefined && item.closable === false) {
              this.tabs.push(page);
            }
            this.pages.push(page);
          }
        }
      });
    };
    getPages(this.routes, 'menu');
  }
}

export default AudTabPage;
